package com.qianhui.servlet;

import com.qianhui.bean.XMLTransferCustomerServiceMessage;
import com.qianhui.common.CM;
import com.qianhui.common.CP;
import com.qianhui.common.GlobalConfig;
import com.qianhui.common.IStatus;
import com.qianhui.dao.BuyerDAO;
import com.qianhui.pojo.Buyer;
import weixin.popular.api.UserAPI;
import weixin.popular.bean.message.EventMessage;
import weixin.popular.bean.user.User;
import weixin.popular.bean.xmlmessage.XMLTextMessage;
import weixin.popular.support.TokenManager;
import weixin.popular.util.SignatureUtil;
import weixin.popular.util.XMLConverUtil;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.*;

/**
 * 服务端事件消息接收
 *
 * @author Yi
 */
@WebServlet("/wechat.do")
public class ReceiveServlet extends HttpServlet
{

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    // 从官方获取
    private String token = GlobalConfig.token;

    // 重复通知过滤 时效60秒
    private static Set<String> expireSet = new HashSet<>(60);

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        ServletInputStream inputStream = request.getInputStream();
        ServletOutputStream outputStream = response.getOutputStream();
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");

        List<String> validList = new ArrayList<String>();
        validList.add(signature);
        validList.add(timestamp);
        validList.add(nonce);
        if (CM.validAtLeastOneIsEmpty(validList))
        {
            return;
        }

        // 首次请求申请验证,返回echostr
        if (echostr != null)
        {
            outputStreamWrite(outputStream, echostr);
            return;
        }

        // 验证请求签名
        if (!signature.equals(SignatureUtil.generateEventMessageSignature(token, timestamp, nonce)))
        {
            System.out.println("The request signature is invalid");
            return;
        }

        if (inputStream != null)
        {
            // 转换XML
            EventMessage eventMessage;
            try
            {
                eventMessage = XMLConverUtil.convertToObject(EventMessage.class, inputStream);
            } catch (Exception e)
            {
                e.printStackTrace();
                return;
            }
            String expireKey = eventMessage.getFromUserName() + "__" + eventMessage.getToUserName() + "__" + eventMessage.getMsgId() + "__" + eventMessage.getCreateTime();
            if (expireSet.contains(expireKey))
            {
                // 重复通知不作处理
                return;
            }
            else
            {
                expireSet.add(expireKey);
            }

            if ("text".equals(eventMessage.getMsgType()))
            {

                // String message_content = new
                // String(eventMessage.getContent().getBytes(), "utf-8");
                String message_content = eventMessage.getContent();
                if (message_content.contains("你好") || message_content.contains("在吗") || message_content.contains("客服") || message_content.contains("售后") || message_content.contains("投诉"))
                {
                    System.out.println("text:" + message_content + ",发送文本进入客服模式");
                    XMLTransferCustomerServiceMessage message = new XMLTransferCustomerServiceMessage(eventMessage.getFromUserName(), eventMessage.getToUserName());
                    message.outputStreamWrite(outputStream);
                    return;
                }
                else
                {
                    String result = "";
                    if (message_content.contains("什么时候发货"))
                    {
                        result = "您好，您拍下的24个小时内就可以为您安排发货的呢。";
                    }
                    else if (message_content.contains("快递"))
                    {
                        result = "根据当地保税仓指定快递。";
                    }
                    else if (message_content.contains("质量"))
                    {
                        result = "您好，仟滙商品是官方正货正品，质量都是有保证的。";
                    }
                    else if (message_content.contains("退换货"))
                    {
                        result = "您好，此类商品属于特殊商品，如非质量问题，暂不支持退换货服务。如有质量问题请在工作时间与我们客服联系，我们会第一时间为你处理申请的哦。";
                    }
                    else if (message_content.contains("实物和图片有差异"))
                    {
                        result = "您好，仟滙商品保证与原厂同步更新包装的哦，包装更换期间新旧包装随机发货哦，商城上的图片有可能没来得及更新，但是绝对都是正品哦，请你放心。";
                    }
                    else if (message_content.contains("赠品"))
                    {
                        result = "您好，请你关注我们的活动信息哦，有活动我们会第一时间公布在商城上的哦~~";
                    }
                    else
                    {
                        result = "您好，感谢您对西普茗茶商品的信赖与支持，请您致电我们的人工客服热线020-86535919，由我们的专业客服为您解答。\r\n人工客服工作时间：周一至周五9:30-18:00。\r\n您也可以输入“客服”接入人工在线客服，谢谢！";
                        // result = new
                        // TulingApiProcess().getTulingResult(message_content);
                        // System.out.println("text:" + message_content +
                        // ",进入图灵机器人,回复:" + result);
                    }

                    // 创建回复
                    XMLTextMessage xmlTextMessage = new XMLTextMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), result);
                    // 回复
                    xmlTextMessage.outputStreamWrite(outputStream);
                    return;
                }

            }
            else if ("event".equals(eventMessage.getMsgType()))
            {
                // 判断事件类型
                // 如果为扫描带参数二维码事件,用户未关注时，进行关注后的事件推送
                if (eventMessage.getEvent().equals("subscribe") && eventMessage.getEventKey().startsWith("qrscene_"))
                {
                    BuyerDAO buyerDAO = new BuyerDAO();

                    String eventKey = eventMessage.getEventKey();
                    String current_buyerQrcodeId = eventKey.replaceAll("qrscene_", "");

                    int buyerQrcodeId = Integer.parseInt(current_buyerQrcodeId);
                    Buyer introducer_buyer = buyerDAO.findByBuyerQrcodeId(buyerQrcodeId);

                    String current_wechat_id = eventMessage.getFromUserName();
                    Buyer current_buyer = buyerDAO.findByBuyerWeChatId(current_wechat_id);
                    // 如果当前用户是第一次关注时
                    if (current_buyer == null)
                    {
                        current_buyer = new Buyer();
                        current_buyer.setBuyerId(CM.getRandomTwentyFivePrimaryKeyId());
                        current_buyer.setBuyerWechat(current_wechat_id);
                        current_buyer.setBuyerPoints(0);
                        current_buyer.setBuyerStatus(IStatus.BUYER_STATUS_USED);
                        current_buyer.setBuyerRegisterTime(new Timestamp(Calendar.getInstance().getTimeInMillis()));

                        User user = UserAPI.userInfo(TokenManager.getToken(GlobalConfig.appID), current_wechat_id);
                        if (!CM.validIsEmptyWithTrim(user.getNickname()))
                        {
                            String nick_name_filter_str = CM.filterEmoji(user.getNickname());
                            if (!CM.validIsEmptyWithTrim(nick_name_filter_str))
                            {
                                int n_length = nick_name_filter_str.length();
                                current_buyer.setBuyerNickname(nick_name_filter_str.substring(0, n_length > 50 ? 50 : n_length));
                            }
                        }
                        if (user.getSex() != null)
                        {
                            current_buyer.setBuyerSex(String.valueOf(user.getSex()));
                        }
                        if (!CM.validIsEmptyWithTrim(user.getCity()))
                        {
                            current_buyer.setBuyerCity(user.getCity());
                        }
                        if (!CM.validIsEmptyWithTrim(user.getCountry()))
                        {
                            current_buyer.setBuyerCountry(user.getCountry());
                        }
                        if (!CM.validIsEmptyWithTrim(user.getProvince()))
                        {
                            current_buyer.setBuyerProvince(user.getProvince());
                        }
                        if (!CM.validIsEmptyWithTrim(user.getHeadimgurl()))
                        {
                            current_buyer.setBuyerHeadimgurl(user.getHeadimgurl());
                        }
                    }

                    if (!introducer_buyer.getBuyerId().equals(current_buyer.getBuyerId()))
                    {
                        current_buyer.setBuyerIntroducer(introducer_buyer.getBuyerId());
                        Buyer buyerResult = buyerDAO.save(current_buyer);

                        //用户扫码关注时发送推送信息给上线
                        if (buyerResult != null)
                        {
                            CP.push_new_user_info(buyerResult);
                        }
                    }

                    String result = "您好，感谢您对西普茗茶商品的信赖与支持，请您致电我们的人工客服热线020-86535919，由我们的专业客服为您解答。\r\n人工客服工作时间：周一至周五9:30-18:00，敬请您耐心等待，谢谢！";
                    // 创建回复
                    XMLTextMessage xmlTextMessage = new XMLTextMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), result);
                    // 回复
                    xmlTextMessage.outputStreamWrite(outputStream);
                    return;
                }
                // 如果为扫描带参数二维码事件,用户已关注时的事件推送
                else if (eventMessage.getEvent().equals("SCAN") && eventMessage.getEventKey() != null)
                {
                    String result = "您好，感谢您对西普茗茶商品的信赖与支持，请您致电我们的人工客服热线020-86535919，由我们的专业客服为您解答。\r\n人工客服工作时间：周一至周五9:30-18:00，敬请您耐心等待，谢谢！";
                    // 创建回复
                    XMLTextMessage xmlTextMessage = new XMLTextMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), result);
                    // 回复
                    xmlTextMessage.outputStreamWrite(outputStream);
                    return;
                }
                // 点击菜单拉取消息时的事件推送
                else if (eventMessage.getEvent().equals("CLICK") && eventMessage.getEventKey().equals("V1001_GOOD2"))
                {
                    System.out.println("点击菜单进入客服模式");
                    XMLTransferCustomerServiceMessage message = new XMLTransferCustomerServiceMessage(eventMessage.getFromUserName(), eventMessage.getToUserName());
                    message.outputStreamWrite(outputStream);
                    return;
                }
            }

            String result = "您好，感谢您对西普茗茶商品的信赖与支持，请您致电我们的人工客服热线020-86535919，由我们的专业客服为您解答。\r\n人工客服工作时间：周一至周五9:30-18:00，敬请您耐心等待，谢谢！";
            // 创建回复
            XMLTextMessage xmlTextMessage = new XMLTextMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), result);
            // 回复
            xmlTextMessage.outputStreamWrite(outputStream);
            return;
        }
        outputStreamWrite(outputStream, "");
    }

    /**
     * 数据流输出
     *
     * @param outputStream
     * @param text
     * @return
     */
    private boolean outputStreamWrite(OutputStream outputStream, String text)
    {
        try
        {
            outputStream.write(text.getBytes("utf-8"));
        } catch (UnsupportedEncodingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        this.doPost(req, resp);
    }
}
